﻿/*
 * Created By: Bharati On 04-Oct-10 @ 16:31
 * 
 */
 using System.Collections.Generic;
 using System.Collections;
using System;

namespace Jas
{

	public class ElementMarker<TElement>:IEnumerable<TElement>
	{

		ArrayManager<Byte> byteList;
		ArrayManager<UInt16>wordMarker;
		ArrayManager<UInt32>dWordMarker;
		
		Action<UInt32> marker;
		
		public TElement[] array;
		
		Int32 lastIndex;

		public ElementMarker(TElement[] array,Int32 capacity,Int32 preAllocationDelta)
		{
			byteList=new ArrayManager<Byte>(capacity,preAllocationDelta);
			this.array = array;
			lastIndex=0;
			marker=markAsByte;
		}
		
		public ElementMarker(TElement[] array):this(array,255,64){}
		
		public ElementMarker():this(null){}
		
		public void mark(Int32 elementIndex)
		{
			marker.Invoke((UInt32)elementIndex);
		}
		
		public void markAsByte(UInt32  index)
		{
			if(index>UInt16.MaxValue){
				marker=markAsDWord;
				dWordMarker=new ArrayManager<UInt32>(16,8);
				marker.Invoke(index);
			}else
			if(index>Byte.MaxValue){
				marker=markAsWord;
				wordMarker=new ArrayManager<UInt16>(16,8);
				marker.Invoke(index);
			}else{
				byteList.add((Byte)index);
				lastIndex=byteList.lastIndex;
			}
		}
		
		public void markAsWord(UInt32 index)
		{
			if(index>UInt16.MaxValue){
				marker=markAsDWord;
				dWordMarker=new ArrayManager<UInt32>(16,8);
				marker.Invoke(index);
			}else{
				
				wordMarker.add((UInt16)index);
				lastIndex=wordMarker.lastIndex;
			}
		}
		
		public void markAsDWord(UInt32 index)
		{
			dWordMarker.add(index);
			lastIndex=dWordMarker.lastIndex;
		}
		
		
		
		
		
		public IEnumerator<TElement> GetEnumerator()
		{
			if(array==null) yield break;
			for(Int32 i=0;i<byteList.currentIndex;i++)
			yield return array[byteList[i]];
			
			for(Int32 i=0;i<wordMarker.currentIndex;i++)
			yield return array[wordMarker[i]];
			
			for(Int32 i=0;i<dWordMarker.currentIndex;i++)
			yield return array[dWordMarker[i]];
		}
		
		IEnumerator IEnumerable.GetEnumerator()
		{
			return array.GetEnumerator();
		}
		
		
		
	}
}
